maybe_broadcast(any) = any
maybe_broadcast(e::Expr) =
    if detected(e, :~)
        :($broadcast($(unweave(e))))
    else
        e
    end

decompose_assignment(e) =
    MacroTools.@match e begin
        ( key_ = value_ ) => (key, maybe_broadcast(value))
        ( object_.field_) => field, :($object.$field)
        s_Symbol => (s, s)
        any_ => error("Unable to decompose assignment $any")
    end

make_kw(e) = Expr(:kw, decompose_assignment(e)...)
make_kw(w::WithContext) = make_kw(w.expression)

make_pair(e) = begin
    key, value = decompose_assignment(e)
    Expr(:tuple, Meta.quot(key), value)
end
make_pair(w::WithContext) = make_pair(w.expression)

add_dots(fieldnames, symbol) = begin
    fields = ImmutableDict{Symbol, Any}()
    for field in fieldnames
        fields = ImmutableDict(fields, field => Expr(:., symbol, Meta.quot(field) ) )
    end
    fields
end
